package com.hucheng.reconciliation.biz;

import com.hucheng.reconciliation.entity.AccountCheckBatchDO;
import com.hucheng.reconciliation.entity.AccountCheckBatchMistakeDO;
import com.hucheng.reconciliation.entity.ReconciliationDetailsDO;
import com.hucheng.reconciliation.mapper.AccountCheckBatchMapper;
import com.hucheng.reconciliation.mapper.AccountCheckBatchMistakeMapper;
import com.hucheng.reconciliation.mapper.AlipayOrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: 凉白开不加冰
 * @Version: 0.0.1V
 * @Date: 2019-08-06
 * @Description: 类描述
 **/
@Slf4j
@Component
public class ReconciliationCheckBiz {

    @Autowired
    private AlipayOrderMapper alipayOrderMapper;

    @Autowired
    private AccountCheckBatchMapper accountCheckBatchMapper;

    @Autowired
    private AccountCheckBatchMistakeMapper accountCheckBatchMistakeMapper;


    @Transactional(rollbackFor = Exception.class)
    public void checkBiz(String dataStr) {

        /** step1：查询支付宝及平台账单 **/
        List<ReconciliationDetailsDO> lists = alipayOrderMapper.list(null, dataStr);

        if (lists.size() == 0) {
            log.info("对账单没有数据,直接返回");
            return;
        }

        List<AccountCheckBatchMistakeDO> listsMistake = new ArrayList<>();
        int mistakeCount = 0;
        int tradeCount = 0;
        BigDecimal tradeAmount = new BigDecimal(0);
        BigDecimal refundAmount = new BigDecimal(0);

        /** step2：比对订单 **/
        for (ReconciliationDetailsDO reconciliationDetailsDO : lists) {
            if (reconciliationDetailsDO.getOrderAmount().equals(reconciliationDetailsDO.getOrderPrice())) {
                //金额对新增对账批次成功笔数
                tradeAmount = tradeAmount.add(reconciliationDetailsDO.getOrderAmount());
                refundAmount = refundAmount.add(reconciliationDetailsDO.getOrderAmount());
            } else {
                //生成异常订单
                AccountCheckBatchMistakeDO accountCheckBatchMistakeDO = new AccountCheckBatchMistakeDO();
                accountCheckBatchMistakeDO.setStatus(1);
                accountCheckBatchMistakeDO.setRemark("支付宝异常订单");
                accountCheckBatchMistakeDO.setBatchNo(dataStr.replaceAll("-", ""));
                accountCheckBatchMistakeDO.setBillDate(dataStr);
                accountCheckBatchMistakeDO.setBillType("ALIPAY");
                accountCheckBatchMistakeDO.setTradeNo(reconciliationDetailsDO.getTradeNo());
                accountCheckBatchMistakeDO.setOrderNumber(reconciliationDetailsDO.getOrderNumber());
                accountCheckBatchMistakeDO.setOrderAmount(reconciliationDetailsDO.getOrderAmount());
                accountCheckBatchMistakeDO.setIsDel(0);
                listsMistake.add(accountCheckBatchMistakeDO);
                mistakeCount++;
            }
            tradeCount++;
        }

        /** step3：入库对账记录 **/
        AccountCheckBatchDO accountCheckBatchDO = new AccountCheckBatchDO();
        accountCheckBatchDO.setStatus(1);
        accountCheckBatchDO.setRemark("支付宝对账单");
        accountCheckBatchDO.setBatchNo(dataStr.replaceAll("-", ""));
        accountCheckBatchDO.setBillDate(dataStr);
        accountCheckBatchDO.setBillType("ALIPAY");
        accountCheckBatchDO.setMistakeCount(mistakeCount);
        accountCheckBatchDO.setTradeCount(tradeCount);
        accountCheckBatchDO.setTradeAmount(tradeAmount);
        accountCheckBatchDO.setRefundAmount(refundAmount);
        accountCheckBatchDO.setIsDel(0);
        accountCheckBatchMapper.insert(accountCheckBatchDO);

        /** step4：入库有误订单记录 **/
        if (listsMistake.size() > 0) {
            accountCheckBatchMistakeMapper.insert(listsMistake);
        }
    }


    public void checkBiz2(String dataStr) {

        List<ReconciliationDetailsDO> lists = new ArrayList<>();
        List<ReconciliationDetailsDO> myLists = new ArrayList<>();
        for (int i = 0; i < 1000000; i++) {
            ReconciliationDetailsDO reconciliationDetailsDO = new ReconciliationDetailsDO();
            reconciliationDetailsDO.setOrderNumber("20190813" + i);
            reconciliationDetailsDO.setTradeNo("20190813" + i);
            reconciliationDetailsDO.setOrderAmount(new BigDecimal(10));
            reconciliationDetailsDO.setPayAmount("10");
            reconciliationDetailsDO.setTotalAmount("10");
            reconciliationDetailsDO.setStatus("1");
            reconciliationDetailsDO.setOrderPrice(new BigDecimal(10));
            reconciliationDetailsDO.setBusinessType("ALIPAY");

            lists.add(reconciliationDetailsDO);

            reconciliationDetailsDO = new ReconciliationDetailsDO();
            reconciliationDetailsDO.setOrderNumber("20190813" + i);
            reconciliationDetailsDO.setTradeNo("20190813" + i);
            reconciliationDetailsDO.setOrderAmount(new BigDecimal(10));
            reconciliationDetailsDO.setPayAmount("10");
            reconciliationDetailsDO.setTotalAmount("10");
            reconciliationDetailsDO.setStatus("1");
            reconciliationDetailsDO.setOrderPrice(new BigDecimal(10));
            reconciliationDetailsDO.setBusinessType("ALIPAY");

            myLists.add(reconciliationDetailsDO);
        }

        myLists.get(100).setOrderAmount(new BigDecimal(20));
        myLists.get(999).setOrderAmount(new BigDecimal(20));
        myLists.get(888).setOrderAmount(new BigDecimal(20));
        myLists.get(777).setOrderAmount(new BigDecimal(20));
        myLists.get(8989).setOrderAmount(new BigDecimal(20));
        myLists.get(999999).setOrderAmount(new BigDecimal(20));
        myLists.get(11111).setOrderAmount(new BigDecimal(20));
        myLists.get(89289).setOrderAmount(new BigDecimal(20));
        myLists.get(898339).setOrderAmount(new BigDecimal(20));
        myLists.get(894489).setOrderAmount(new BigDecimal(20));
        myLists.get(893389).setOrderAmount(new BigDecimal(20));
        myLists.get(811989).setOrderAmount(new BigDecimal(20));
        myLists.get(228989).setOrderAmount(new BigDecimal(20));

        Long start = System.currentTimeMillis();

        Map<String, ReconciliationDetailsDO> maps = new LinkedHashMap<>();
        for (int i = 0; i < lists.size(); i++) {
            maps.put(lists.get(i).getOrderNumber(), lists.get(i));
        }

        for (int i = 0; i < myLists.size(); i++) {
            ReconciliationDetailsDO reconciliationDetailsDO1 = maps.get(myLists.get(i).getOrderNumber());
            ReconciliationDetailsDO reconciliationDetailsDO2 = myLists.get(i);

            if (reconciliationDetailsDO1.getOrderAmount().equals(reconciliationDetailsDO2.getOrderAmount())) {
                //金额一致
//                System.out.println("订单号: " + reconciliationDetailsDO1.getOrderNumber() + ", 金额一致");
            } else {
                //金额不一致
                System.out.println("订单号: " + reconciliationDetailsDO1.getOrderNumber() + ", 金额不一致");
            }
        }

        Long end = System.currentTimeMillis();
        System.out.println("执行时间：" + (end - start) + "ms");


    }

    /**
     * 创建基于Levenshtein distance算法的比对工具类
     */
//    private static final Javers javers =
//            JaversBuilder.javers()
//                    .withListCompareAlgorithm(ListCompareAlgorithm.LEVENSHTEIN_DISTANCE)
//                    .build();
    public static void main(String[] args) {

        ReconciliationCheckBiz reconciliationCheckBiz = new ReconciliationCheckBiz();
        reconciliationCheckBiz.checkBiz2("");

//        ReconciliationDetailsDO reconciliationDetailsDO = new ReconciliationDetailsDO();
//        reconciliationDetailsDO.setOrderNumber("123");
//        reconciliationDetailsDO.setTradeNo("123");
//        reconciliationDetailsDO.setOrderAmount(new BigDecimal(1));
//        reconciliationDetailsDO.setPayAmount("1");
//        reconciliationDetailsDO.setTotalAmount("1");
//        reconciliationDetailsDO.setStatus("1");
//        reconciliationDetailsDO.setOrderPrice(new BigDecimal(1));
//        reconciliationDetailsDO.setBusinessType("ALIPAY");
//
//
//        ReconciliationDetailsDO myReconciliationDetailsDO = new ReconciliationDetailsDO();
//        myReconciliationDetailsDO.setOrderNumber("456");
//        myReconciliationDetailsDO.setTradeNo("123");
//        myReconciliationDetailsDO.setOrderAmount(new BigDecimal(2));
//        myReconciliationDetailsDO.setPayAmount("1");
//        myReconciliationDetailsDO.setTotalAmount("1");
//        myReconciliationDetailsDO.setStatus("1");
//        myReconciliationDetailsDO.setOrderPrice(new BigDecimal(1));
//        myReconciliationDetailsDO.setBusinessType("ALIPAY");
//
//        // 进行比对
//        Diff diff = javers.compare(reconciliationDetailsDO, myReconciliationDetailsDO);
//        // 列出两笔流水的所有不同
//        List<Change> changes = diff.getChanges();
//        for (Change valueChange : changes) {
//            // 打印不同Field跟Field的中文名
//            ValueChange change = (ValueChange) valueChange;
//            System.out.println(String.format("%s不匹配,期望值%s,实际值%s", change.getPropertyName(), change.getLeft(),
//                    change.getRight()));
//        }

    }
}
